﻿using Autofac;
using Autofac.Extensions.DependencyInjection;
using Md.Api;
using Md.Api.Controllers.Filters;
using Md.Api.DDD;
using Md.Core.Moddlewares;
using Md.Im.Service;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Microsoft.OpenApi.Models;
using Newtonsoft.Json;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
// api接口地址：http://*:5800/swagger/index.html

// 关闭系统自带的模型验证过滤器
builder.Services.Configure<ApiBehaviorOptions>(opt => opt.SuppressModelStateInvalidFilter = true);

builder.Services.AddControllers(opt =>
{
    // 添加自定义模型验证过滤器
    opt.Filters.Add(typeof(MdAuthAttribute));
    // opt.Filters.Add(typeof(MdModelValidateAttribute));
});

// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(swagger =>
{
    // 参考资料：https://blog.csdn.net/qq_36425493/article/details/127752781
    swagger.SwaggerDoc("v1", new OpenApiInfo
    {
        Title = "Md.Api",
        Version = "v1",
        Description = "MD通用管理系统API接口文档"
    });
    
    // 给api接口增加描述信息
    var apiFile = Path.Combine(AppContext.BaseDirectory, "Md.Api.Controllers.xml");
    var apiPath = Path.Combine(AppContext.BaseDirectory, apiFile);
    swagger.IncludeXmlComments(apiPath, true);
    swagger.OrderActionsBy(o => o.RelativePath);

    // 给请求实体增加描述信息
    var modelFile = Path.Combine(AppContext.BaseDirectory, "Md.Api.Model.xml");
    var modelPath = Path.Combine(AppContext.BaseDirectory, modelFile);
    swagger.IncludeXmlComments(modelPath, true);
});

builder.Services.AddRedisSetup();

#region ===注入获取HTTP上下文服务===
builder.Services.TryAddSingleton<IHttpContextAccessor, HttpContextAccessor>();
#endregion

#region ===MVC修改控制器描述===
builder.Services.AddCors(opt =>
{
    //var urls = "http://192.168.100.202:8082,http://192.168.100.202:3303".Split(",");
    //opt.AddPolicy("cors_allow_orgins", bul => bul.WithOrigins(urls).AllowAnyMethod().AllowAnyHeader().AllowCredentials());

    opt.AddPolicy("cors_allow_orgins", bul => bul.AllowAnyMethod().SetIsOriginAllowed(_ => true).AllowAnyHeader().AllowCredentials());
});

builder.Services.AddHttpContextAccessor();
builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
builder.Services.AddMvc(config =>
{
    config.RespectBrowserAcceptHeader = true;
})
.AddFormatterMappings(options => options.SetMediaTypeMappingForFormat("json", "application/json"))
.AddFormatterMappings(options => options.SetMediaTypeMappingForFormat("xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"))
.AddFormatterMappings(options => options.SetMediaTypeMappingForFormat("jpeg", "image/jpeg"))
.AddFormatterMappings(options => options.SetMediaTypeMappingForFormat("jpg", "image/jpeg"))
.AddJsonOptions(opt =>
{
    opt.JsonSerializerOptions.Converters.Add(new DatetimeJsonConverter());
});
#endregion

#region ===autofac===
builder.Services.AddControllers().AddControllersAsServices();

builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());

builder.Host.ConfigureContainer<ContainerBuilder>(autofaczBuilder =>
{
    // 注册服务
    autofaczBuilder.RegisterModule(new AutofacModule());
});

// 替换第三方服务注入容器
builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());
#endregion

var app = builder.Build();

// Configure the HTTP request pipeline.
//if (app.Environment.IsDevelopment())
//{
    app.UseSwagger();
    app.UseSwaggerUI(opt =>
    {
        opt.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
    });
//}

// 设置环境变量，用于读取appsettings.{env}.json配置
Environment.SetEnvironmentVariable("Environment", app.Environment.EnvironmentName);

// 重定向https
// app.UseHttpsRedirection();
app.UseMdImServer(new ImServerOptions
{
    Redis = new FreeRedis.RedisClient(JsonConfig.JsonRead("MdRedis:MdConnection")),
    Servers = JsonConfig.JsonRead("MdIm:Servers").Split(","),
    Server = JsonConfig.JsonRead("MdIm:Server")
});

ImHelper.Initialization(new ImClientOptions
{
    Redis = new FreeRedis.RedisClient(JsonConfig.JsonRead("MdRedis:MdConnection")),
    Servers = JsonConfig.JsonRead("MdIm:Servers").Split(",")
});

ImHelper.Instance.OnSend += (s, e) => Console.WriteLine($"ImClient.SendMessage(server={e.Server},data={JsonConvert.SerializeObject(e.Message)})");

ImHelper.EventBus(t =>
    {
        Console.WriteLine(t.clientId + "上线了");
        var onlineUids = ImHelper.GetClientListByOnLine();
        ImHelper.SendMessage(t.clientId, onlineUids, $"用户{t.clientId}上线了");
    },
    t => Console.WriteLine(t.clientId + "下线了")
);

app.UseCors("cors_allow_orgins");

app.UseAuthorization();

app.MapControllers();

app.Run();